/*
 *     Prionace - A file navigator to manage your files
 *
 *     Copyright (C) 2012 Francivan Bezerra
 *
 *     This file is part of Prionace.
 *
 *     Prionace is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Prionace is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with Prionace.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.fba.prionace.ui;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileNotFoundException;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.fba.prionace.file.FileTransferHandler;
import org.fba.prionace.file.JFile;
import org.fba.prionace.ui.viewer.IconsViewer;
import org.fba.prionace.ui.viewer.Viewer;

public class FilesPane extends JPanel implements ActionListener,
		ChangeListener, MouseListener {

	private JTabbedPane tab;

	private PathBar pathBar;

	private JButton scrollLeft;

	private JButton scrollRight;

	private JButton previous;

	private JButton next;

	private StatusBar statusBar;

	public FilesPane() {
		super();
		init();
	}

	private void init() {
		tab = new JTabbedPane();
		pathBar = new PathBar();
		statusBar = new StatusBar();

		KeyAction keyAction = new KeyAction();
		keyAction.setTarget(this);
		keyAction.initKeys();

		tab.addChangeListener(this);
		tab.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		tab.setTransferHandler(new FileTransferHandler());

		JPanel navigationPane = new JPanel(new GridBagLayout());
		GridBagConstraints constraints = new GridBagConstraints();

		scrollLeft = new JButton("«");
		scrollLeft.setActionCommand("scroll left");
		scrollLeft.setVisible(false);
		scrollLeft.setFocusable(false);
		scrollLeft.addMouseListener(pathBar);
		constraints.fill = GridBagConstraints.VERTICAL;
		constraints.gridx = 0;
		navigationPane.add(scrollLeft, constraints);

		scrollRight = new JButton("»");
		scrollRight.setVisible(false);
		scrollRight.setFocusable(false);
		scrollRight.addMouseListener(pathBar);
		constraints.gridx = 2;
		navigationPane.add(scrollRight, constraints);

		previous = new JButton("\u25C4");
		previous.setFocusable(false);
		previous.setToolTipText("Anterior");
		previous.addActionListener(this);
		constraints.gridx = 4;
		navigationPane.add(previous, constraints);

		next = new JButton("\u25BA");
		next.setFocusable(false);
		next.setToolTipText("Próximo");
		next.addActionListener(this);
		constraints.gridx = 5;
		navigationPane.add(next, constraints);

		JSeparator separator = new JSeparator();
		separator.setOrientation(SwingConstants.VERTICAL);
		constraints.gridx = 3;
		navigationPane.add(separator, constraints);

		pathBar.registerScrollButton(scrollLeft);
		pathBar.registerScrollButton(scrollRight);
		constraints.gridx = 1;
		constraints.fill = GridBagConstraints.BOTH;
		constraints.ipadx = 1;
		constraints.weightx = .1;
		navigationPane.add(pathBar, constraints);

		JPanel pathPane = new JPanel(new BorderLayout());
		pathPane.add(navigationPane, BorderLayout.CENTER);

		setLayout(new BorderLayout());
		add(pathPane, BorderLayout.NORTH);
		add(tab, BorderLayout.CENTER);
		add(statusBar, BorderLayout.SOUTH);
	}

	public PathBar getPathBar() {
		return pathBar;
	}

	public StatusBar getStatusBar() {
		return statusBar;
	}

	public JTabbedPane getTab() {
		return tab;
	}

	public void refreshStatusBar() {
		int totalDirs = getSelectedViewer().getTotalDirs();
		int totalFiles = getSelectedViewer().getTotalFiles();
		String[] singular = { " pasta", " arquivo" };
		String[] plural = { " pastas", " arquivos" };
		StringBuffer info = new StringBuffer("Total: ");

		if (totalDirs > 0) {
			info.append(totalDirs);
			info.append(totalDirs == 1 ? singular[0] : plural[0]);
		}

		if (totalDirs > 0 && totalFiles > 0) {
			info.append(", ");
		}

		if (totalFiles > 0) {
			info.append(totalFiles);
			info.append(totalFiles == 1 ? singular[1] : plural[1]);
		}

		if (totalDirs + totalFiles == 0) {
			info.append("vazio");
		}

		info.append(".");
		getStatusBar().setText(info.toString());
	}

	public void refreshBars() {
		if (getSelectedViewer().getCurrentPath() == null) {
			return;
		}
		pathBar.setCurrentPath(getSelectedViewer().getCurrentPath());
		setTabTitle(getSelectedViewer().getCurrentDirName());
		refreshStatusBar();
		addClickListeners();
	}

	public void setTabTitle(String title) {
		TabTitle tabTitle = (TabTitle) tab.getTabComponentAt(tab
				.getSelectedIndex());

		if (tabTitle == null) {
			tabTitle = new TabTitle();
		}

		tabTitle.getTitle().setText(title);
	}

	public void setCurrentPath(File path) {
		try {
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			getSelectedViewer().setCurrentPath(path);
			setTabTitle(getSelectedViewer().getCurrentDirName());
			refreshStatusBar();
			setCursor(null);
		} catch (FileNotFoundException ex) {
			ExceptionHandler.showException(ex, this);
		}
	}

	public void setCurrentPath(String path) {
		setCurrentPath(new File(path));
	}

	public void addViewer(Viewer viewer) {
		TabTitle title = new TabTitle(viewer.getCurrentDirName(), tab);
		viewer.setOwner(this);
		tab.addTab(null, viewer);
		tab.setTabComponentAt(tab.getTabCount() - 1, title);
	}

	public void addViewer(File path) {
		// TODO pegar o viewer de um viewer factory
		try {
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			Viewer viewer = new IconsViewer(path);
			addViewer(viewer);
			tab.setSelectedIndex(tab.getTabCount() - 1);
			setCursor(null);
		} catch (FileNotFoundException ex) {
			ExceptionHandler.showException(ex, this);
		}
	}

	public Viewer getSelectedViewer() {
		return (Viewer) tab.getSelectedComponent();
	}

	public void showRoots() {
		setTabTitle("Computador");
		getSelectedViewer().showRoots();
	}

	private void addClickListeners() {
		for (JFile pathButton : pathBar.getPathButtons()) {
			if (pathButton.getActionListeners().length == 0) {
				pathButton.addMouseListener(this);
			}
		}
	}

	public void actionPerformed(ActionEvent e) {
		try {
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			if (e.getSource() == previous) {
				getSelectedViewer().movePrevious();
			} else {
				getSelectedViewer().moveNext();
			}
			refreshBars();
			setCursor(null);
		} catch (FileNotFoundException ex) {
			ExceptionHandler.showException(ex, this);
		}
	}

	public void stateChanged(ChangeEvent e) {
		refreshBars();
	}

	public void mouseClicked(MouseEvent e) {
		JFile clicked = (JFile) e.getSource();

		if (e.getButton() == MouseEvent.BUTTON1) {
			setCurrentPath(clicked.getFile());
		} else if (e.getButton() == MouseEvent.BUTTON2) {
			addViewer(clicked.getFile());
		}

		pathBar.firePathChanged();
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}
}
